import { Object3D, Quaternion, Vector2, Vector3 } from "three";
import Entity, { EntityConfig } from "../Core/Entity";
import { MaxDistance } from "../Utils/Util";
import { AreaItem } from "src/Core/World";

export default class Bullet extends Entity {
  mesh: Object3D;
  constructor(_config: EntityConfig, _mesh: Object3D) {
    super(_config);
    this.mesh = _mesh;
    this.behaviors.push(...["Shoot", "MeasurementFar", "Collision"]);
  }

  async Builder() {
    super.Builder();
    this.model.position.copy(this.mesh.getWorldPosition(new Vector3()));
    let qua = this.mesh.getWorldQuaternion(new Quaternion());
    this.model.rotation.setFromQuaternion(qua);
  }

  Shoot() {
    let v3 = new Vector3();
    v3.setFromMatrixColumn(this.model.matrix, 0);
    v3.crossVectors(this.model.up, v3);
    this.model.position.addScaledVector(v3, -0.04);
  }

  distance: number;
  MeasurementFar() {
    let pos = this.model.getWorldPosition(new Vector3());
    let troopPos = world.troop.group.getWorldPosition(new Vector3());
    this.distance = pos.distanceTo(troopPos);

    if (this.distance > MaxDistance) {
      this.Dispose();
    }
  }

  Collision() {
    let v = new Vector2(Math.trunc(this.model.position.x), Math.trunc(this.model.position.z));
    let { i, j, x, y } = world.GetIndexAndPlusNumber(v);

    try {
      let items = Object.values(world.areaMatrix[x][i][y][j]);
      for (let k = 0; k < items.length; k++) {
        let m = items[k] as AreaItem;
        if (m.value.model.userData.obb.intersectsOBB(this.model.userData.obb)) {
          m.value.UnderAttack();
          this.Dispose();
        }
      }
    } catch {}
  }
}
